/**
 din 持续低20ms,dout产生一个上升沿脉冲
**/
module  key_filter
#(
    parameter MAX_CNT = 20'd1000000 //计数器计数最大值
)
(
    input   wire    clk     ,   //系统时钟50Mhz
    input   wire    rst_n   ,   //全局复位
    input   wire    din      ,   //按键输入信号
    output  reg     dout        //key_flag为1时表示消抖后检测到按键被按下
);

reg     [19:0]  cnt_20ms  ;
wire    cnt_20ms_add;
wire    cnt_20ms_end;

//cnt_20ms:如果时钟的上升沿检测到外部按键输入的值为低电平时，计数器开始计数
always@(posedge clk or negedge rst_n)
    if(rst_n == 1'b0)
        cnt_20ms <= 20'b0;
    else if(cnt_20ms_end)
    		cnt_20ms <= 20'b0;
    else if(cnt_20ms_add)
         cnt_20ms <= cnt_20ms + 1'b1;
    else
         cnt_20ms<=cnt_20ms;

 //计数器转移条件
 assign cnt_20ms_add =din == 1'b0 && cnt_20ms < MAX_CNT;
 assign cnt_20ms_end =din==1 ;

//dout:当计数满20ms后产生按键有效标志位
always@(posedge clk or negedge rst_n)
    if(rst_n == 1'b0)
        dout <= 1'b0;
    else    if(cnt_20ms > MAX_CNT - 6 && cnt_20ms< MAX_CNT-2)
        dout <= 1'b1;
    else
        dout <= 1'b0;

endmodule

